#pragma once
#include <stdarg.h>
#include <string>
#include <ctime>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>

enum
{
    Debug = 0,
    Warning,
    Error,
    Fatal,
    Unknow
};

enum
{
    Screen = 10,
    Onefile,
    Classfile
};

std::string LevelToS(int level)
{
    switch (level)
    {
    case Debug:
        return "Debug";
        break;
    case Warning:
        return "Warning";
        break;
    case Error:
        return "Error";
        break;
    case Fatal:
        return "Fatal";
        break;
    default:
        return "Unknow";
        break;
    }
}

#define default_name "log."
#define logdir "log"

class Log
{
public:
    Log() : _filename(default_name)
    {
        mkdir(logdir, 0776);
    }

    void changemod(int n)
    {
        _type = n;
    }

    string extime()
    {
        const time_t currtime = time(nullptr);
        struct tm *t;
        t = localtime(&currtime);
        string s;
        s += to_string(t->tm_year + 1900);
        s += "-";
        s += to_string(t->tm_mon + 1);
        s += "-";
        s += to_string(t->tm_mday);
        s += " ";
        s += to_string(t->tm_hour + 1);
        s += ":";
        s += to_string(t->tm_min + 1);
        s += ":";
        s += to_string(t->tm_sec);
        

        return s;
    }


    void PrintoneFile(const string& name,const string& mes)
    {
        FILE* file = fopen(name.c_str(), "a");
        if(file ==  NULL) return;
        fprintf(file,"%s",mes.c_str());
        fclose(file);

    }

    void PrintFileName(const string &leveler, const string &mes)
    {
        string truename = logdir;
        truename += "/";
        truename += default_name;
        truename += leveler;

        PrintoneFile(truename,mes);

    }

    void writelog(const string &leveler, const string &mes)
    {
        switch (_type)
        {
        case Screen:
            cout << mes << endl;
            break;
        case Onefile:
            PrintFileName("all",mes);
            break;
        case Classfile:
            PrintFileName(leveler,mes);
            break;
        default:
            break;
        }
    }

    void LogMessage(int level, const char *format, ...)
    {
        char right[1024];
        va_list args;
        va_start(args, format);
        vsnprintf(right, sizeof(right), format, args);
        va_end(args);

        char left[1024];
        string currtime = extime();
        string leveler = LevelToS(level);
        snprintf(left, sizeof(left), "[%s][%s][%s] ", leveler.c_str(), currtime.c_str(), to_string(getpid()).c_str());

        string s(left);
        s += right;

        writelog(leveler, s);
    }

    ~Log()
    {
    }

private:
    int _type;
    string _filename;
};

Log log;

class Conf
{
public:
    Conf()
    {
        log.changemod(Onefile);
    }

    ~Conf()
    {}

};
Conf conf;